<?php
/**
 * This file is part of workerman.
 *
 * Licensed under The MIT License
 * For full copyright and license information, please see the MIT-LICENSE.txt
 * Redistributions of files must retain the above copyright notice.
 *
 * @author walkor<walkor@workerman.net>
 * @copyright walkor<walkor@workerman.net>
 * @link http://www.workerman.net/
 * @license http://www.opensource.org/licenses/mit-license.php MIT License
 */

/**
 * 用于检测业务代码死循环或者长时间阻塞等问题
 * 如果发现业务卡死，可以将下面declare打开（去掉//注释），并执行php start.php reload
 * 然后观察一段时间workerman.log看是否有process_timeout异常
 */
use \GatewayWorker\Lib\Gateway;
use \Lib\Message;

/**
 * 主逻辑
 * 主要是处理 onConnect onMessage onClose 三个方法
 * onConnect 和 onClose 如果不需要可以不用实现并删除
 */
class Events
{
    /**
     * 当客户端连接时触发
     * 如果业务不需此回调可以删除onConnect
     *
     * @param int $client_id 连接id
     * @link http://gatewayworker-doc.workerman.net/gateway-worker-development/onconnect.html
     */
    public static function onConnect($client_id)
    {
        self::sendDataToCurrentClient('connect', $client_id, 0, 'Welcome 成都众联思索科技');
    }

   /**
    * 当客户端发来消息时触发
    * @param int $client_id 连接id
    * @param mixed $message 具体消息
    */
   public static function onMessage($client_id, $message) {
     //  $message = json_decode($message, true);
     //    $message_type = $message['type'];
       $message_array = @json_decode($message, true) ?: array();
       // var_dump($message_array);
       // 如果数据中指定了数据类型
       if (isset($message_array['type'])) {
           // 取得请求的类型
           $type = preg_replace_callback('/_([a-z])/', function ($match) {
               return strtoupper($match[1]);
           }, strtolower($message_array['type']));
           // 处理这个类型的类方法名称
           $method = $type.'Message';
           // 如果有这个方法
           if (is_callable(__CLASS__.'::'.$method)) {
               // 没有设置packid则设置为null
               if (!isset($message_array['packid'])) {
                   $message_array['packid'] = null;
               }
               // 如果不在白名单中的，那么需要检查登录
               if (!in_array($type, array('login'))) {
                   // 检查登录并提醒
                   if (!self::logged($message_array['packid'])) {
                       return; // 如果没有登录就终止
                   }
               }
               unset($message_array['type']); //删除数据中type字段
               // 调用type对应的类方法进行处理
               //try{
               self::$method($client_id, $message_array, $message);
               /*}catch (\Exception $e) {
                   echo $e->getMessage();
                   $msg = 'Server internal exception';
                   self::sendDataToCurrentClient('send_message', null, 1000, $msg);
               }*/
           } else {
               // 类方法不存在或未被支持，则发送错误提示信息到客户端
               $msg = "Message type is not supported: {$message_array['type']}";
               self::sendDataToCurrentClient('send_message', null, 1002, $msg);
           }
       } else {
           // 没有指定类型，无法继续后续工作，发送错误描述
           $msg = 'Message type is not specified';
           self::sendDataToCurrentClient('send_message', null, 1001, $msg);
       }




//       switch($message_type) {
//           case 'init':
//               // uid

//               break;
//           case 'addUser' :
//               //添加用户
//               $add_message = [
//                   'message_type' => 'addUser',
//                   'data' => [
//                       'type' => 'friend',
//                       'avatar'   => $message['data']['avatar'],
//                       'username' => $message['data']['username'],
//                       'groupid'  => $message['data']['groupid'],
//                       'id'       => $message['data']['id'],
//                       'sign'     => $message['data']['sign']
//                   ]
//               ];
//               Gateway::sendToAll( json_encode($add_message), null, $client_id );
//               return;
//               break;
//           case 'delUser' :
//               //删除用户
//               $del_message = [
//                   'message_type' => 'delUser',
//                   'data' => [
//                       'type' => 'friend',
//                       'id'       => $message['data']['id']
//                   ]
//               ];
//               Gateway::sendToAll( json_encode($del_message), null, $client_id );
//               return;
//               break;
//           case 'addGroup':
//               //添加群组
//               $uids = explode( ',', $message['data']['uids'] );
//               $client_id_array = [];
//               foreach( $uids as $vo ){
//                   $ret = Gateway::getClientIdByUid( $vo );  //当前组中在线的client_id
//                   if( !empty( $ret ) ){
//                       $client_id_array[] = $ret['0'];
//
//                       Gateway::joinGroup($ret['0'], $message['data']['id']);  //将这些用户加入群组
//                   }
//               }
//               unset( $ret, $uids );
//
//               $add_message = [
//                   'message_type' => 'addGroup',
//                   'data' => [
//                       'type' => 'group',
//                       'avatar'   => $message['data']['avatar'],
//                       'id'       => $message['data']['id'],
//                       'groupname'     => $message['data']['groupname']
//                   ]
//               ];
//               Gateway::sendToAll( json_encode($add_message), $client_id_array, $client_id );
//               return;
//               break;
//           case 'joinGroup':
//               //加入群组
//               $uid = $message['data']['uid'];
//               $ret = Gateway::getClientIdByUid( $uid ); //若在线实时推送
//               if( !empty( $ret ) ){
//                   Gateway::joinGroup($ret['0'], $message['data']['id']);  //将该用户加入群组
//
//                   $add_message = [
//                       'message_type' => 'addGroup',
//                       'data' => [
//                           'type' => 'group',
//                           'avatar'   => $message['data']['avatar'],
//                           'id'       => $message['data']['id'],
//                           'groupname'     => $message['data']['groupname']
//                       ]
//                   ];
//                   Gateway::sendToAll( json_encode($add_message), [$ret['0']], $client_id );  //推送群组信息
//               }
//
//               return;
//               break;
//           case 'addMember':
//               //添加群组成员
//               $uids = explode( ',', $message['data']['uid'] );
//               $client_id_array = [];
//               foreach( $uids as $vo ){
//                   $ret = Gateway::getClientIdByUid( $vo );  //当前组中在线的client_id
//                   if( !empty( $ret ) ){
//                       $client_id_array[] = $ret['0'];
//
//                       Gateway::joinGroup($ret['0'], $message['data']['id']);  //将这些用户加入群组
//                   }
//               }
//               unset( $ret, $uids );
//
//               $add_message = [
//                   'message_type' => 'addGroup',
//                   'data' => [
//                       'type' => 'group',
//                       'avatar'   => $message['data']['avatar'],
//                       'id'       => $message['data']['id'],
//                       'groupname'     => $message['data']['groupname']
//                   ]
//               ];
//               Gateway::sendToAll( json_encode($add_message), $client_id_array, $client_id );  //推送群组信息
//               return;
//               break;
//           case 'removeMember':
//               //将移除群组的成员的群信息移除，并从讨论组移除
//               $ret = Gateway::getClientIdByUid( $message['data']['uid'] );
//               if( !empty( $ret ) ){
//
//                   Gateway::leaveGroup($ret['0'], $message['data']['id']);
//
//                   $del_message = [
//                       'message_type' => 'delGroup',
//                       'data' => [
//                           'type' => 'group',
//                           'id'       => $message['data']['id']
//                       ]
//                   ];
//                   Gateway::sendToAll( json_encode($del_message), [$ret['0']], $client_id );
//               }
//
//               return;
//               break;
//           case 'delGroup':
//               //删除群组
//               $del_message = [
//                   'message_type' => 'delGroup',
//                   'data' => [
//                       'type' => 'group',
//                       'id'       => $message['data']['id']
//                   ]
//               ];
//               Gateway::sendToAll( json_encode($del_message), null, $client_id );
//               return;
//               break;
//           case 'chatMessage':
//               $db1 = Db::instance('db1');  //数据库链接
//               // 聊天消息
//               $type = $message['data']['to']['type'];
//               $to_id = $message['data']['to']['id'];
//               $uid = $_SESSION['id'];
//
//               $chat_message = [
//                   'message_type' => 'chatMessage',
//                   'data' => [
//                       'username' => $_SESSION['username'],
//                       'avatar'   => $_SESSION['avatar'],
//                       'id'       => $type === 'friend' ? $uid : $to_id,
//                       'type'     => $type,
//                       'content'  => htmlspecialchars($message['data']['mine']['content']),
//                       'timestamp'=> time()*1000,
//                   ]
//               ];
//               //聊天记录数组
//               $param = [
//                   'fromid' => $uid,
//                   'toid' => $to_id,
//                   'fromname' => $_SESSION['username'],
//                   'fromavatar' => $_SESSION['avatar'],
//                   'content' => htmlspecialchars($message['data']['mine']['content']),
//                   'timeline' => time(),
//                   'needsend' => 0
//               ];
//               switch ($type) {
//                   // 私聊
//                   case 'friend':
//                       // 插入
//                       $param['type'] = 'friend';
//                       if( empty( Gateway::getClientIdByUid( $to_id ) ) ){
//                           $param['needsend'] = 1;  //用户不在线,标记此消息推送
//                       }
//                       $db1->insert('snake_chatlog')->cols( $param )->query();
//                       return Gateway::sendToUid($to_id, json_encode($chat_message));
//                   // 群聊
//                   case 'group':
//                       $param['type'] = 'group';
//                       $db1->insert('snake_chatlog')->cols( $param )->query();
//                       return Gateway::sendToGroup($to_id, json_encode($chat_message), $client_id);
//               }
//               return;
//               break;
//           case 'hide':
//           case 'online':
//               $status_message = [
//                   'message_type' => $message_type,
//                   'id'           => $_SESSION['id'],
//               ];
//               $_SESSION['online'] = $message_type;
//               Gateway::sendToAll(json_encode($status_message));
//               return;
//               break;
//           case 'ping':
//               return;
//           default:
//               echo "unknown message $message" . PHP_EOL;
//       }
   }

    public static function loginMessage($client_id, array $message = array()){
        // 取得客户端数据包各参数
        $uid = isset($message['uid']) ? (int) $message['uid'] : null;
        $oauth_token_secret = isset($message['oauth_token_secret']) ? (string) $message['oauth_token_secret'] : null;
        // 如果都正确传递，那么尝试登陆用户
        if ($uid && $oauth_token_secret ) {
            // 调用登陆接口尝试登陆，如果能正确登陆，则发送登陆成功的提示
            if (Message::login($client_id, $uid,  $oauth_token_secret)) {
                self::sendDataToCurrentClient('login', (int) Message::getLoggedUserInfo('uid'));
            //    self::pushMessageDataToCurrent();
                return ; // 登录已经成功，后面不在执行，所以直接返回
            }
        }
        // 无法登陆或数据包参数不完整，则发送登陆错误信息
        self::sendDataToCurrentClient('login', $uid, 1004, 'Login failed');
    }

    /**
     * 当用户断开连接时触发
     * @param int $client_id 连接id
     */
    public static function onClose($client_id)
    {
        Message::logout($client_id); //退出用户
    }


    /**
     * 向当前连接用户发送数据包
     * @param  string $type   消息类型
     * @param  mixed  $result 消息数据
     * @param  int    $status 数据状态
     * @param  string $msg    数据描述消息
     * @return bool
     */
    protected static function sendDataToCurrentClient($type, $result = null, $status = 0, $msg = '')
    {
        $data = json_encode(array(
            'type' => $type,
            'result' => $result,
            'status' => $status,
            'msg' => $msg,
        ));

        return Gateway::sendToCurrentClient($data);
    }
    /**
     * 用户注销登录
     * @param  string $packid      客户端的包ID
     * @param  bool   $send_notice 是否发送登录通知
     * @return bool   如果已登录返回true，否则返回false
     */
    protected static function logged($packid, $send_notice = true)
    {
        $logged = Message::logged();
        if (!$logged && $send_notice) {
            self::sendDataToCurrentClient('login', $packid, 1003, 'Not logged in');
        }
        return $logged;
    }
}
